package com.eagle.nenaboot.common.codec;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;

/**
 * <p>
 *  粘包拆包处理
 * <p>
 *
 * @author eagle liu
 * @since 2020/3/13 21:14
 */
public class Spliter extends LengthFieldBasedFrameDecoder {
	/**
	 * http://
	 * UTF-8编码:一个英文字符等于一个字节,英文标点占一个字节,因此上述字符有
	 * 7个字节，因为1个字节等于8位，所以7字节=56位，每一位代表一个2进制数字
	 * netty中，字符编码是以16进制（0x）存在, 而一个16进制对应四个2进制的数字。因此，上述56位的2进制=14位的16进制
	 * netty中，LENGTH_FIELD_OFFSET的位移量单位是字节，因为一个字节=8位=2个16进制， 得出14位的16进制=7位字节
	 */
    private static final int LENGTH_FIELD_OFFSET = 7;
    private static final int LENGTH_FIELD_LENGTH = 4;

    public Spliter() {
		/**
		 * maxFrameLength - 发送的数据包最大长度
		 * lengthFieldOffset - 长度域偏移量，指的是长度域位于整个数据包字节数组中的下标；
		 * lengthFieldLength - 长度域的自己的字节数长度。 表示长度域占用4个字节
		 */
		super(Integer.MAX_VALUE, LENGTH_FIELD_OFFSET, LENGTH_FIELD_LENGTH);
    }

    @Override
    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
//		ByteBuf.readableBytes() 返回可读的字节数
        if (in.getInt(in.readerIndex()) != PacketCode.MAGIC_NUMBER) {
            ctx.channel().close();
            return null;
        }

        return super.decode(ctx, in);
    }
}
